import React, { useState, useRef, useEffect } from 'react'
import { Capacitor } from '@capacitor/core'
import { useSystemOverlay } from '../hooks/useSystemOverlay'
import './FloatingButton.scss'

interface FloatingButtonProps {
  onToggle?: () => void
}

interface Position {
  x: number
  y: number
}

export const FloatingButton: React.FC<FloatingButtonProps> = ({ onToggle }) => {
  const [position, setPosition] = useState<Position>({ x: 20, y: 80 })
  const [isDragging, setIsDragging] = useState(false)
  const [isPointerDown, setIsPointerDown] = useState(false)
  const [dragStart, setDragStart] = useState<Position>({ x: 0, y: 0 })
  const [showSystemOverlayOption, setShowSystemOverlayOption] = useState(false)
  const buttonRef = useRef<HTMLDivElement>(null)
  const isMobile = Capacitor.isNativePlatform()
  const rafRef = useRef<number | null>(null)
  const pendingPosRef = useRef<Position | null>(null)
  const MOVE_THRESHOLD = 6 // px，移动阈值，避免轻微抖动导致点击失效
  const suppressClickRef = useRef(false)
  
  const {
    hasPermission,
    isSystemOverlayVisible,
    checkPermission,
    requestPermission,
    showSystemOverlay,
    hideSystemOverlay
  } = useSystemOverlay()

  // 从localStorage恢复位置
  useEffect(() => {
    const savedPosition = localStorage.getItem('floating-button-position')
    if (savedPosition) {
      try {
        const parsed = JSON.parse(savedPosition)
        setPosition(parsed)
      } catch (error) {
        console.warn('Failed to parse saved position:', error)
      }
    }
  }, [])

  // 保存位置到localStorage
  const savePosition = (pos: Position) => {
    localStorage.setItem('floating-button-position', JSON.stringify(pos))
  }

  // 限制位置在屏幕范围内
  const constrainPosition = (pos: Position): Position => {
    const buttonSize = 56 // 按钮大小
    const margin = 10 // 边距
    
    return {
      x: Math.max(margin, Math.min(window.innerWidth - buttonSize - margin, pos.x)),
      y: Math.max(margin, Math.min(window.innerHeight - buttonSize - margin, pos.y))
    }
  }

  // 鼠标/触摸开始
  const handleStart = (clientX: number, clientY: number) => {
    setIsPointerDown(true)
    setDragStart({ x: clientX, y: clientY })
  }

  // 鼠标/触摸移动
  const handleMove = (clientX: number, clientY: number) => {
    if (!isPointerDown) return
    const deltaX = clientX - dragStart.x
    const deltaY = clientY - dragStart.y

    if (!isDragging) {
      const dist = Math.hypot(deltaX, deltaY)
      if (dist < MOVE_THRESHOLD) return
      setIsDragging(true)
    }

    const next = constrainPosition({ x: position.x + deltaX, y: position.y + deltaY })
    pendingPosRef.current = next
    if (!rafRef.current) {
      rafRef.current = requestAnimationFrame(() => {
        if (pendingPosRef.current) setPosition(pendingPosRef.current)
        rafRef.current = null
      })
    }
    setDragStart({ x: clientX, y: clientY })
  }

  // 鼠标/触摸结束
  const handleEnd = () => {
    setIsPointerDown(false)
    if (rafRef.current) {
      cancelAnimationFrame(rafRef.current)
      rafRef.current = null
    }
    // 拖拽结束，吸附到左右边缘
    if (isDragging) {
      const buttonSize = 56
      const margin = 10
      const centerX = position.x + buttonSize / 2
      const snapLeft = margin
      const snapRight = window.innerWidth - buttonSize - margin
      const snapX = centerX < window.innerWidth / 2 ? snapLeft : snapRight
      const snapped = constrainPosition({ x: snapX, y: position.y })
      setPosition(snapped)
      savePosition(snapped)
      setIsDragging(false)
    }
  }

  // 鼠标事件
  const handleMouseDown = (e: React.MouseEvent) => {
    e.preventDefault()
    handleStart(e.clientX, e.clientY)
  }

  const handleMouseMove = (e: MouseEvent) => {
    handleMove(e.clientX, e.clientY)
  }

  const handleMouseUp = () => {
    handleEnd()
  }

  // 触摸事件
  const handleTouchStart = (e: React.TouchEvent) => {
    // 阻止滚动，便于拖拽
    e.preventDefault()
    const touch = e.touches[0]
    handleStart(touch.clientX, touch.clientY)
  }

  const handleTouchMove = (e: TouchEvent) => {
    e.preventDefault()
    const touch = e.touches[0]
    handleMove(touch.clientX, touch.clientY)
  }

  const handleTouchEnd = (e: TouchEvent) => {
    const wasDragging = isDragging
    if (wasDragging) e.preventDefault()
    handleEnd()
    // 作为点击：未触发拖拽则认为是点击
    if (!wasDragging) {
      suppressClickRef.current = true // 抑制随后触发的 click
      setTimeout(() => (suppressClickRef.current = false), 300)
      handlePrimaryAction()
    }
  }

  // 添加全局事件监听：按下后开始监听，用于检测阈值与拖拽
  useEffect(() => {
    if (isPointerDown) {
      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('mouseup', handleMouseUp)
      document.addEventListener('touchmove', handleTouchMove, { passive: false })
      document.addEventListener('touchend', handleTouchEnd, { passive: false })

      return () => {
        document.removeEventListener('mousemove', handleMouseMove)
        document.removeEventListener('mouseup', handleMouseUp)
        document.removeEventListener('touchmove', handleTouchMove)
        document.removeEventListener('touchend', handleTouchEnd)
      }
    }
  }, [isPointerDown, isDragging, dragStart, position])

  // 主动作：移动端切换系统悬浮；非移动端（或无插件）回落到 onToggle（若提供）
  const handlePrimaryAction = async () => {
    if (isMobile) {
      // 切换系统悬浮
      const permitted = await checkPermission()
      if (!permitted) {
        const granted = await requestPermission()
        if (!granted) {
          alert('需要悬浮窗权限才能使用系统级悬浮功能')
          return
        }
      }

      if (isSystemOverlayVisible) {
        await hideSystemOverlay()
      } else {
        const success = await showSystemOverlay({ x: position.x, y: position.y })
        if (!success) {
          alert('显示系统悬浮窗失败')
        }
      }
    } else if (onToggle) {
      onToggle()
    }
  }

  const handleClick = async (e: React.MouseEvent) => {
    if (suppressClickRef.current) {
      e.preventDefault()
      suppressClickRef.current = false
      return
    }
    // 如果刚刚拖拽过，不触发点击
    if (isDragging) {
      e.preventDefault()
      return
    }

    // 触觉反馈
    if (isMobile) {
      try {
        await Capacitor.Plugins.Haptics?.impact({ style: 'light' })
      } catch (error) {
        console.warn('Haptics not available:', error)
      }
    }

    await handlePrimaryAction()
  }

  const handleLongPress = async () => {
    if (!isMobile) return
    
    // 显示系统级悬浮窗选项
    setShowSystemOverlayOption(true)
  }

  const handleSystemOverlayToggle = async () => {
    // 先重新检查权限状态
    const currentPermission = await checkPermission()
    
    if (!currentPermission) {
      const granted = await requestPermission()
      if (!granted) {
        alert('需要悬浮窗权限才能使用系统级悬浮功能')
        setShowSystemOverlayOption(false)
        return
      }
      // 权限获取后再次检查
      const recheckPermission = await checkPermission()
      if (!recheckPermission) {
        alert('权限检查失败，请确保已在设置中允许悬浮窗权限')
        setShowSystemOverlayOption(false)
        return
      }
    }

    if (isSystemOverlayVisible) {
      await hideSystemOverlay()
    } else {
      const success = await showSystemOverlay({ x: position.x, y: position.y })
      if (!success) {
        alert('显示系统悬浮窗失败')
      }
    }
    
    setShowSystemOverlayOption(false)
  }

  return (
    <div 
      ref={buttonRef}
      className={`floating-button ${isSystemOverlayVisible ? 'active' : ''} ${
        isDragging ? 'dragging' : ''
      } ${isSystemOverlayVisible ? 'system-overlay-active' : ''}`}
      style={{
        position: 'fixed',
        left: `${position.x}px`,
        top: `${position.y}px`,
        right: 'auto',
        bottom: 'auto'
      }}
    >
      <button
        className="floating-btn"
        onClick={handleClick}
        onMouseDown={handleMouseDown}
        onTouchStart={handleTouchStart}
        onContextMenu={handleLongPress}
        aria-label="切换系统悬浮"
      >
        <span className="floating-btn-icon">✨</span>
      </button>
      
      {showSystemOverlayOption && isMobile && (
        <div className="system-overlay-menu">
          <button 
            className="overlay-option"
            onClick={handleSystemOverlayToggle}
          >
            {isSystemOverlayVisible ? '关闭系统悬浮' : '开启系统悬浮'}
          </button>
          <button 
            className="overlay-option cancel"
            onClick={() => setShowSystemOverlayOption(false)}
          >
            取消
          </button>
        </div>
      )}
    </div>
  )
}
